package com.fly.visit.service.init.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import com.fly.core.util.JsonBeanUtils;
import com.fly.core.util.ShellExecutor;
import com.fly.visit.entity.Article;
import com.fly.visit.entity.BlogData;
import com.fly.visit.service.init.DataInitor;

import lombok.extern.slf4j.Slf4j;

/**
 * 通过WebApi接口初始化
 */
@Slf4j
@Order(1)
@Component
public class BlogApiDataInitor implements DataInitor
{
    /**
     * 分页查询每页大小
     */
    private int pageSize = 50;
    
    @Override
    public boolean init(String userName, List<Article> articles)
    {
        try
        {
            // 容器运行，镜像需安装curl
            log.info("########## start init for {} ...", userName);
            List<Article> all = new ArrayList<>();
            
            /*****************************
             * 终止条件判断思路有2种:</br>
             * 1.当前解析到的数据<pageSize，弊端：记录为pageSize整数倍时，会多执行一次接口，解析异常时也会立即终止</br>
             * 2.list.size()<record.total，弊端：解析异常时不会立即终止
             ******************************/
            IntStream.rangeClosed(1, 100)
                .peek(i -> log.info("########### page: {}", i))
                .mapToObj(i -> String.format("curl -e \"blog.csdn.net\" \"https://blog.csdn.net/community/home-api/v1/get-business-list?page=%s&size=%s&businessType=blog&username=%s\"", i, pageSize, userName))
                .map(cmd -> ShellExecutor.execute(cmd))
                .anyMatch(json -> addArticlesCount(json, all) < pageSize);
            int count = all.size();
            log.info("########### articles total: {}", count);
            log.info("########### average：{}", all.stream().mapToLong(a -> a.getViewCount()).average().getAsDouble());
            articles.addAll(all.stream().sorted(Comparator.comparing(Article::getViewCount)).collect(Collectors.toList()).subList(0, Math.min(20, count)));
            return !CollectionUtils.isEmpty(articles);
        }
        catch (Exception e)
        {
            log.error(e.getMessage(), e);
            return false;
        }
    }
    
    /**
     * 解析json为BlogData并追加数据
     * 
     * @param json
     * @return 追加成功记录数
     */
    private int addArticlesCount(String json, List<Article> list)
    {
        try
        {
            BlogData blogData = JsonBeanUtils.jsonToBean(json, BlogData.class, true);
            List<Article> nowArticles = blogData.getData().getList();
            if (!nowArticles.isEmpty())
            {
                list.addAll(nowArticles);
                return nowArticles.size();
            }
        }
        catch (IOException e)
        {
            log.error(e.getMessage(), e);
        }
        return 0;
    }
}